import { Module } from "@nestjs/common";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { UsersModule } from "../users/users.module";
import { JwtModule } from "@nestjs/jwt";
import { AUTHOR_INFO } from "src/providers/author";
import {  AsyncConfig, AsyncData } from "src/providers/async.config";
import { CustomConfigService } from "src/config/config.service";
import { CustomConfigModule } from "src/config/config.module";
import { ASYNC_CONFIG_KEY, AUTHOR_INFO_KEY, TOKEN_SECRET_KEY } from "src/constant/provider.const";

@Module({
  imports: [
    UsersModule, // 静态模块绑定: 它导入 UsersModule, 使得 UsersModule 导出的提供者(UserService)可以在 AuthModule 内部使用
    CustomConfigModule, // 🚀 这个模块不是为了 JwtModule, 而是为了 TOKEN_SECRET_KEY
    JwtModule.registerAsync({ // 模块注册,但是要依赖于其他 service 翻译的数据, 所以要导入 CustomConfigModule 并且 inject ConfigService
      global: true,
      imports: [CustomConfigModule], // 🚀 这里导入 CustomConfigModule, 是为了在 useFactory 中使用 ConfigService
      inject: [CustomConfigService], // 🚀 这里注入 ConfigService, 是为了在 useFactory 中使用它, ConfigService中有 query DB 方法
      useFactory: async (configService: CustomConfigService) => {
        const config = await configService.getConfig();
        return {
          secret: config.secret, // JWTModule注册的时候需要 secret 和  expire
          signOptions: { expiresIn: `${config.expire}h` },
        }
      },
    })
  ],
  controllers: [AuthController],
  providers: [
    /**
     * Standard provider: AuthService
    */
    AuthService, // 标准 provider: AuthService
    /**
     * Custom Async provider - Constant
    */
    { provide: AUTHOR_INFO_KEY  , useValue: AUTHOR_INFO }, // 自定义异步 provider - 常量
    /**
     * Use async provider to get token secret from db
    */
    {
      provide: TOKEN_SECRET_KEY, // 自定义异步 provider - 依赖数据库, 从数据库获取 token 密钥
      useFactory: async (configService: CustomConfigService): Promise<string> => {
        console.info('TOKEN_SECRET_KEY 自定义异步 provider - 从数据库获取 token 密钥 ---- start');
        const config = await configService.getConfig();
        console.info('TOKEN_SECRET_KEY 自定义异步 provider - 从数据库获取 token 密钥 ---- end');
        return config?.secret;
      },
      inject: [CustomConfigService], // 自定义异步 provider - 从数据库获取 token 密钥, 依赖 ConfigService
    },

    /**
     * Custom provider - Factory
    */
    {
      provide: ASYNC_CONFIG_KEY, // 自定义异步 provider - 工厂函数
      useFactory: async (): Promise<AsyncConfig> => {
        return await fetchConfirmFromRemote();
      },
    },
  ],
  // 此处不要再导入 ConfigService, 因为它已经被注册为全局模块
  exports: [AuthService, TOKEN_SECRET_KEY,ASYNC_CONFIG_KEY], // 只有在这里导出了 TOKEN_SECRET_KEY, 才能再其他模块或 provider 中使用, 比如 auth.guard.ts 中
})
export class AuthModule { }


const fetchConfirmFromRemote = async (): Promise<AsyncConfig> => {
  await new Promise(resolve => setTimeout(resolve, 3000));
  console.log('AsyncConfig fetch complete!');
  return AsyncData
}